package util.io.file ;

/**
 * ADAMS Engine Core. 
 * Copyright ⓒ 2010 LGHitachi Co., Ltd. All Rights Reserved.
 * 
 * @Program Name : JLargeBufFileReader.java
 * @Description : 입력 스트림 Read 관리 
 * 
 * @author  : ADAMS Team
 * @version : 1.0
 * @history : 2010. 7. 30. - 최초작성
 */

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class JLargeBufFileReader
    implements JFileReader {

    /**
     * Open 할 File Pointer를 위한 Object Reference Variable
     */
    private FileInputStream fis = null ;

    /**
     * Open 한 File Pointer에 사용될 Buffer Object Reference Variable
     */
    private BufferedInputStream bis = null ;

    /**
     * Open 할 File 의 Name을 위한 Attribute
     */
    private String fName = null ;

    private final int _LINE_LEN = 10000 ;

    private boolean _IS_EOF = false ;

    /**
     * CR = 개행문자,  LF = 커서를 라인의 처음으로
     */
    final static int CR = 0x0d, LF = 0x0a, SP = 0x20, EOF = -1 ;

    
    /**
     * 생성자
     */
    public JLargeBufFileReader () throws FileNotFoundException {
        throw ( new FileNotFoundException (
            "Uage new JLargeBufFileReader(FileName);...." ) ) ;
    }

    /**
     * 생성자
     * 1. File Name Set
     * 2. FileInputStream 생성
     * 3. BufferedInputStream 생성
     * @param fname Read 할 File Name
     */
    public JLargeBufFileReader ( String fname ) throws FileNotFoundException {
        if ( fname == null ) {
            throw ( new FileNotFoundException ( "FILE NAME IS NULL.." ) ) ;
        }
        this.fName = fname ;
        fis = new FileInputStream ( this.fName ) ;
        bis = new BufferedInputStream ( fis ) ;
    }

    /**
     * 파일별 라인을 Read 한다.
     * @return null byte[]
     */
    public byte[] readLine2 () throws IOException {
        return null;
    }
    
    /**
     * 파일에 대한  라인별 Read 한다.
     * @return _b  File에서 Read 한 1 Line 의  byte[]
     */

    public byte[] readLine () throws IOException {
        byte[] _b = new byte[ _LINE_LEN ] ;
        int b = 0 ;

        if ( bis == null ) {
            throw ( new IOException ( "File Not Open...!!!" ) ) ;
        }
        int idx = 0 ;
        while ( true ) {
            b = this.bis.read () ;
            _b[ idx ] = ( byte ) b ;
            if ( b == LF || b == EOF ) {
                break ;
            }
        }

        if ( b == EOF ) {
            finalize () ;

        }
        return _b ;
    }
    
    /**
     * 파일에 대한 라인 개수를 리턴한다.
     * @return -1 파일 라인 개수
     */
    public int getLine() throws IOException {
        return -1;
    }

    /**
     * 파일에서 1 byte씩 Read 한다.
     * @return bret File에서 Read 한 1 Line 의  다음 바이트 Read 
     */
    public int read () throws IOException {
        int bret = SP ;
        bret = this.bis.read () ;
        if ( bret == EOF ) {
            finalize () ;
        }
        return bret ;
    }

    /**
     * Open 한 File에서 File Pointer 를 이동한다.
     * @param pos          이동할 File Pointer 의 위치
     */    
    public void seek ( long pos ) throws IOException {
        bis.skip ( pos ) ;
    }

     /**
     * Open 한 File에서 특정위치에 데이타를 Read 한다.
     * @param b             File에서 Read한 byte data를 저장한 byte배열
     * @param off           File에서 Read할 시작 위치
     * @param len           File에서 Read할 byte길이
     * @return iret         File read 입력  데이타의 다음 바이트 Read
     */    
    public int read ( byte b[], int off, int len ) throws IOException {
        int iret = 0 ;
        iret = bis.read ( b, off, len ) ;
        if ( iret == EOF ) {
            finalize () ;
        }
        return iret ;
    }
    
    /**
     * Open 한 File에서 특정위치에 데이타를 Read 한다.
     * @param b             File에서 Read한 byte data를 저장한 byte배열
     * @return iret         File read 입력  데이타의 다음 바이트 Read
     */      
    public int read ( byte b[] ) throws IOException {
        int iret = 0 ;
        iret = bis.read ( b ) ;
        if ( iret == EOF ) {
            finalize () ;
        }
        return iret ;
    }

    /**
     * Open 한 File과 Buffer Stream을 Close해서 시스템에 자원을 반납한다.
     */
    public void finalize () {
        if ( bis != null ) {
            try {
                fis.close () ;
            } catch ( IOException e ) {
                e.printStackTrace () ;
            }
        }

        if ( fis != null ) {
            try {
                fis.close () ;
            } catch ( IOException e ) {
                e.printStackTrace () ;
            }
        }
    }

    /**
     * Open 한 File에 EOF인지 여부 체크한다.
     * @return     this._IS_EOF true or false 
     */
    public boolean isEOF () {
        return ( this._IS_EOF ) ;
    }
}
